﻿using DevExpress.Utils;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.DXErrorProvider;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace DevTeam
{
    public static class GenericExtensions
    {

        public static void MakeNOTCompulsory(this Control control)
        {
            DevForm form = (DevForm)control.FindForm();
            form.ValidationProvider.SetValidationRule(control, null);
        }


        public static void MakeCompulsory(this Control control, LabelControl label, string ErrorText)
        {
            DevForm form = (DevForm)control.FindForm();

            ConditionValidationRule validator = (ConditionValidationRule)form.cvrEmpty.Clone();
            validator.ErrorType = ErrorType.None;
            form.ValidationProvider.SetValidationRule(control, validator);
            if (!form.InvalidControls.ContainsKey(control))
                form.InvalidControls.Add(control, new DevForm.InvalidControl(label, ErrorText, control));
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="columnName">Virgülle ayrılmış değerlerini almak istediğiniz sütun</param>
        /// <param name="seperator"></param>
        /// <returns></returns>
        public static string GetValuesofSpecifiedColumn(this DataTable dt, string columnName, string seperator)
        {
            string idxs = "";
            foreach (DataRow dr in dt.Rows)
                if (dr[columnName].ToStr() != "")
                    idxs += dr[columnName].ToStr() + seperator;

            idxs = idxs.RemoveIfEndsWith(seperator);

            return idxs;
        }

        public static void MergeColumns(this DataTable t, string MasterColumn, params string[] ChildColumns)
        {
            foreach (DataRow r in t.Rows)
            {
                string result = "";
                string valMaster = r[MasterColumn].ToStr();
                string valSlave = "";
                foreach (string SlaveCol in ChildColumns)
                {
                    valSlave = valSlave + r[SlaveCol].ToStr();
                }
                if (valMaster == string.Empty)
                {
                    result = valSlave;
                }
                else if (valSlave == string.Empty)
                {
                    result = valMaster;
                }
                else
                {
                    result = valMaster + " " + valSlave;
                }

                r[MasterColumn] = result;
            }
            foreach (string SlaveCol in ChildColumns)
            {
                t.Columns.Remove(SlaveCol);
            }

        }


        public static Double SecondsPast(this DateTime date)
        {
            return DateTime.UtcNow.Subtract(date).TotalSeconds;
        }

        public static void AcKapa(this SplitContainerControl sc, bool Acilsin)
        {
            FieldInfo fi = typeof(SplitContainerControl).GetField("containerInfo", BindingFlags.NonPublic | BindingFlags.Instance);
            DevExpress.XtraEditors.Drawing.SplitContainerViewInfo vInfo = fi.GetValue(sc) as DevExpress.XtraEditors.Drawing.SplitContainerViewInfo;
            if ((vInfo.Splitter.IsCollapsed) ^ (!Acilsin))
                vInfo.Splitter.DoExpandCollapseOnClick();
        }

        public static void AutoSize(this SplitContainerControl sc, double oran = 0.5)
        {
            sc.SizeChanged += SplitterSizeChanged;
            SetSplitterPosition(sc, oran);
        }

        private static void SplitterSizeChanged(object sender, EventArgs e)
        {
            SetSplitterPosition(sender as SplitContainerControl);
        }

        private static void SetSplitterPosition(SplitContainerControl sc, double oran = 0.5)
        {
            sc.SplitterPosition = Convert.ToInt32((sc.Horizontal ? sc.Width : sc.Height) * oran);
        }

        public static bool IsNumeric(this object s)
        {
            float output;
            return float.TryParse(s.ToStr(), out output);
        }

        public static DataTable ToDataTable<T>(this List<T> items)
        {
            DataTable dataTable = new DataTable(typeof(T).Name);
            //Get all the properties
            PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo prop in Props)
            {
                //Setting column names as Property names
                dataTable.Columns.Add(prop.Name);
            }
            foreach (T item in items)
            {
                var values = new object[Props.Length];
                for (int i = 0; i < Props.Length; i++)
                {
                    //inserting property values to datatable rows
                    values[i] = Props[i].GetValue(item, null);
                }
                dataTable.Rows.Add(values);
            }
            //put a breakpoint here and check datatable
            return dataTable;
        }

        public static decimal ToDecimal(this object value, decimal ExceptionalReturnValue = 0)
        {
            decimal result = ExceptionalReturnValue;

            if (value != null)
                if (value != DBNull.Value)
                    if (value.ToString() != "")
                        try
                        {
                            result = Convert.ToDecimal(value, CultureInfo.CurrentCulture);

                            //CultureInfo ci = new CultureInfo("en-US");
                            //result = Convert.ToDecimal(value, ci);
                        }
                        catch
                        {

                        }

            return result;
        }



        /// <summary>
        /// Bu fonksyion, aldığı object türünde veriyi integer a çevirir. Çeviremediği durumlarda ExceptionalReturnValue olarak geçilen parametreyi döndürür.
        /// </summary>
        /// <param name="value">Oject türünde herhangi bir parametre. Null ya da DBNull.Value da olabilir.</param>
        /// <returns>Integer a dönüştürülmüş hali ya da hata durumunda ExceptionalReturnValue</returns>
        public static int ToInt(this object value, int ExceptionalReturnValue = 0)
        {
            int result = ExceptionalReturnValue;

            if (value != null)
                if (value != DBNull.Value)
                    if (value.ToString() != "")
                        try
                        {
                            result = Convert.ToInt32(value);
                        }
                        catch
                        {
                        }

            return result;
        }


        public static object ToIntDBNull(this object value)
        {
            if (value != null)
                if (value != DBNull.Value)
                    if (value.ToString() != "")
                        try
                        {
                            int result = Convert.ToInt32(value);
                            return result;
                        }
                        catch
                        {
                        }

            return DBNull.Value;
        }

        public static long ToBigInt(this object value, long ExceptionalReturnValue = 0)
        {
            long result = ExceptionalReturnValue;

            if (value != null)
                if (value != DBNull.Value)
                    if (value.ToString() != "")
                        try
                        {
                            result = Convert.ToInt64(value);
                        }
                        catch
                        {
                        }

            return result;
        }

        public static string ToStr(this object value)
        {
            string result = "";

            if (value != null)
                if (value != DBNull.Value)
                    result = value.ToString().Trim();

            return result;
        }

        public static DateTime ToDate(this object value)
        {
            DateTime result = new DateTime(2000, 1, 1);

            if (value != null)
                if (value != DBNull.Value)
                    DateTime.TryParse(value.ToString(), out result);

            return result;
        }

        public static bool ToBool(this DefaultBoolean value)
        {
            return value == DefaultBoolean.True;
        }

        public static bool ToBool(this object value)
        {
            bool result = false;

            if (value != null)
                if (value != DBNull.Value)
                    if (value.ToString() != "")
                        try
                        {
                            result = Convert.ToBoolean(value);
                        }
                        catch
                        {
                        }
            return result;
        }

        public static DefaultBoolean Toggle(this DefaultBoolean value)
        {

            if (value == DefaultBoolean.True)
                return DefaultBoolean.False;
            else if (value == DefaultBoolean.False)
                return DefaultBoolean.True;
            else //TODO : bu kısım sorun çıkarabilir
                return DefaultBoolean.Default;
        }

        public static string RemoveBetween(this string source, char begin, char end)
        {
            Regex regex = new Regex(string.Format("\\{0}.*?\\{1}", begin, end));
            return regex.Replace(source, string.Empty);
        }

        public static string RemoveIfEndsWith(this string source, string stringToRemove)
        {
            if (source.EndsWith(stringToRemove))
                source = source.Substring(0, source.Length - stringToRemove.Length);

            return source;
        }

        public static bool IsNullOrWhiteSpace(this string value)
        {
            return string.IsNullOrWhiteSpace(value);
        }

        public static object GetCurrentValue(this BindingSource bindingSource, string ColumnName)
        {
            object result = null;
            if (bindingSource != null && bindingSource.Current != null)
            {
                result = ((DataRowView)bindingSource.Current).Row[ColumnName];
            }

            return result;
        }
    }
}